home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / XDME / Src / Key / KeyCodes.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  29KB  |  1,245 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     keycodes.c
  5.  
  6.     DESCRIPTION
  7.     Lowlevel module for evaluation of keycodes and qualifiers
  8.  
  9.     NOTES
  10.     highly amiga - specific
  11.  
  12.     BUGS
  13.     no use of dead-keys
  14.  
  15.     TODO
  16.     deadkey - checking
  17.     qual2iqual
  18.  
  19.     EXAMPLES
  20.  
  21.     SEE ALSO
  22.  
  23.     INDEX
  24.  
  25.     HISTORY
  26.     14-Dez-92 b_null created
  27.     14-Jan-93 b_null added UP
  28.     15-Jan-92 b_null added DeadKeyConvert, removed exit_kb - it caused a GURU
  29.     04 Apr 93 b_null added QUAL_PR*, QUAL_NLK, QUAL_REP; renamed USHORT,UBYTE->TQUAL,TCODE
  30.     30 Apr 93 b_null added is_rawc
  31.     16 Jun 93 b_null introduced "struct keyspec"
  32.     29-Jun-94 b_null Docs updated
  33.     03-Jul-94 b_null Added "DoubleClick-Key"
  34.  
  35. ******************************************************************************/
  36.  
  37. /**************************************
  38.         Includes
  39. **************************************/
  40. #define  KEY_INTERNAL
  41. #include "defs.h"
  42. #include <devices/keymap.h>
  43. #include <devices/console.h>
  44. #include <clib/utility_protos.h>
  45. #include <proto/utility.h>
  46. #ifdef PATCH_NULL
  47. #include "AUTO.h"
  48. #else
  49. #define MK_AUTOINIT(x) void x (void)
  50. #endif /*  */
  51.  
  52. extern UBYTE CtlC;
  53.  
  54.  
  55.  
  56. /**************************************
  57.         Globale Variable
  58. **************************************/
  59.  
  60. Prototype struct Library * ConsoleDevice;
  61. struct Library * ConsoleDevice = NULL;
  62.  
  63. /**************************************
  64.       Interne Defines & Strukturen
  65. **************************************/
  66. typedef struct IOStdReq CIO;
  67.  
  68.  
  69. /* format of entries in lname[] */
  70. #define LN(a,b,c,d)  ((a<<24)|(b<<16)|(c<<8)|d)
  71.  
  72. /* important numbers in lname[] */
  73. #define F1_START  0           /* Function keys */
  74. #define SP_START 10           /* special keys    */
  75. #define CS_START 20           /* cursor keys    */
  76. #define N0_START 24           /* NK numbers    */
  77. #define NS_START N0_START+10   /* NK specials    */
  78. #define MB_START 41           /* Mouse     */
  79.  
  80.  
  81. /* internal representation for qualifiers */
  82. #define QUAL_SHIFT   0x0001 /* ANY SHIFT */
  83. #define QUAL_CTRL    0x0002 /* CONTROL     */
  84. #define QUAL_AMIGA   0x0004 /* ANY AMIGA */
  85. #define QUAL_ALT     0x0008 /* ANY ALT     */
  86. #define QUAL_LMB     0x0010 /* LEFT MOUSE BUTTON   */
  87. #define QUAL_MMB     0x0020 /* MIDDLE MOUSE BUTTON */
  88. #define QUAL_RMB     0x0040 /* RIGHT MOUSE BUTTON  */
  89.  
  90. #define QUAL_UP      0x0080 /* RELEASE - currently this MUST be 0x80 - that value is used in im.Code */
  91.  
  92. #define QUAL_XTX     0x0100 /* Extended Qualifiers for multi-key strokes - Removed after each keypress */
  93. #define QUAL_XTY     0x0200
  94. #define QUAL_XTZ     0x0400
  95.  
  96. #define QUAL_REP     0x0800 /* REPEAT */
  97.  
  98. #define QUAL_PRX     0x1000 /* Permanent Extended Qualifiers for multi-key strokes */
  99. #define QUAL_PRY     0x2000
  100. #define QUAL_PRZ     0x4000
  101.  
  102. #define QUAL_NLK     0x8000 /* NUMLOCK - refers only to numeric keypad */
  103.  
  104.  
  105. /* additional pseudo-intuition qualifiers - referring to the Quals above */
  106. #define EXTQUALIFIER_X    0x00100000
  107. #define EXTQUALIFIER_Y    0x00200000
  108. #define EXTQUALIFIER_Z    0x00400000
  109.  
  110. #define EXTQUALIFIER_NLK 0x0800000
  111.  
  112. #define PERQUALIFIER_X    0x01000000
  113. #define PERQUALIFIER_Y    0x02000000
  114. #define PERQUALIFIER_Z    0x04000000
  115.  
  116. #define EXTQUALIFIER_UP 0x00800000 /* this one is not used yet - the key-up information is part of ie.keyCode */
  117.  
  118.  
  119. /* some hardcoded ( I hope ) keys on Amiga Keyboard */
  120. #define CSPC  0x40 /* Spacebar    */
  121. #define CB_S  0x41 /* BackSpace */
  122. #define CENT  0x43 /* Enter    */
  123. #define CRET  0x44 /* Return    */
  124.  
  125.  
  126. /**************************************
  127.         Interne Variable
  128. **************************************/
  129. static UBYTE ctoa[128];    /* code to ascii  */
  130. static UBYTE cstoa[128];   /* code shifted to ascii */
  131.  
  132. static TQUAL qualignore[128]; /* which key ignores to which qualifier by default */ /* PATCH_NULL [04 Apr 1993] : added */
  133. static UBYTE is_rawc[128];    /* which key can be used in a DeadKeyConversion */    /* PATCH_NULL [30 Apr 1993] : added */
  134.  
  135. static ULONG lname[] =
  136. {
  137.     /* FuncKeys */
  138.     LN('f','1', 0 , 0  ), LN('f','2', 0 , 0  ), LN('f','3', 0 , 0  ),
  139.     LN('f','4', 0 , 0  ), LN('f','5', 0 , 0  ), LN('f','6', 0 , 0  ),
  140.     LN('f','7', 0 , 0  ), LN('f','8', 0 , 0  ), LN('f','9', 0 , 0  ),
  141.     LN('f','1','0', 0  ),
  142.     /* Specials */
  143.     LN('h','e','l', 0  ), LN('e','s','c', 0  ), LN('d','e','l', 0  ),
  144.     LN('b','a','c', 0  ), LN('b','s', 0 , 0  ), LN('t','a','b', 0  ),
  145.     LN('r','e','t',CRET), LN('e','n','t',CENT), LN('s','p','c',CSPC),
  146.     LN('s','p','a',CSPC),
  147.     /* Cursor */
  148.     LN('u','p', 0 , 0  ), LN('d','o','w', 0  ), LN('r','i','g', 0  ),
  149.     LN('l','e','f', 0  ),
  150.     /* Numeric digits */
  151.     LN('n','k','0', 0  ), LN('n','k','1', 0  ), LN('n','k','2', 0  ),
  152.     LN('n','k','3', 0  ), LN('n','k','4', 0  ), LN('n','k','5', 0  ),
  153.     LN('n','k','6', 0  ), LN('n','k','7', 0  ), LN('n','k','8', 0  ),
  154.     LN('n','k','9', 0  ),
  155.     /* Numeric Specials */
  156.     LN('n','k', 0 , 0  ), LN('n','k', 0 , 0  ), LN('n','k','/', 0  ),
  157.     LN('n','k','*', 0  ), LN('n','k','+', 0  ), LN('n','k','-', 0  ),
  158.     LN('n','k','.', 0  ),
  159.     /* Mouse Buttons */
  160.     LN('l','m','b',0x68), LN('m','m','b',0x6A), LN('r','m','b',0x69),
  161.     LN('m','m','o',0x6B),
  162.     /* /* WARNING - THESE VALUES MIGHT INTERFERE WITH OTHER KEYS */
  163.     LN('l','m','2',0x67), LN('l','m','3',0x66), LN('l','m','4',0x65),
  164.     LN('m','m','2',0x64), LN('m','m','3',0x63), LN('m','m','4',0x62),
  165.     LN('r','m','2',0x61), LN('r','m','3',0x60), LN('r','m','4',0x5f)
  166.     /* /* WARNING - THESE VALUES MIGHT INTERFERE WITH OTHER KEYS */
  167. };
  168.  
  169.  
  170.  
  171. /**************************************
  172.        Interne Prototypes
  173. **************************************/
  174.  
  175.  
  176. /*****************************************************************************
  177.  
  178.     NAME
  179.     keyboard_init
  180.  
  181.     PARAMETER
  182.     void
  183.  
  184.     RESULT
  185.     -/-
  186.  
  187.     RETURN
  188.     void
  189.  
  190.     DESCRIPTION
  191.     initializes the variables used in the current Module
  192.  
  193.     NOTES
  194.     That functon MUST be called before any other call to any
  195.     other functions of the key-modules
  196.  
  197.     BUGS
  198.     if a dead- and a deadable-key are next to each other,
  199.     tables might get corrupted (but I cannot imagine that)
  200.  
  201.     EXAMPLES
  202.  
  203.     SEE ALSO
  204.  
  205.     INTERNALS
  206.  
  207.     HISTORY
  208.     14-Dec-92  b_null included & modified
  209.  
  210. ******************************************************************************/
  211.  
  212. Prototype void keyboard_init (void);
  213.  
  214. void keyboard_init (void)
  215. {
  216.     static struct InputEvent ievent = {
  217.     NULL,
  218.     IECLASS_RAWKEY,
  219.     0, 0, 0, NULL,          /* 0,0 */ /* time */
  220.     };
  221.     UBYTE buf[32];
  222.     short i,   /* TCODE */
  223.       len; /* short */
  224.  
  225. /* printf ("keyboard_init\n"); */
  226. /*    clrmem (qualignore, sizeof (qualignore)); */ /* PATCH_NULL [04 Apr 1993] : added */
  227.  
  228.     /* ---- Init unshifted keys (ctoa) */
  229.     /*        together w/ longkeys and is_rawc */
  230.  
  231.     ievent.ie_Qualifier        = 0;
  232.     ievent.ie_position.ie_addr = NULL;
  233.     for (i = 0; i < 128; ++i) {
  234.     ievent.ie_Code = i;
  235.  
  236.     len = RawKeyConvert (&ievent, buf, 32, NULL);
  237.  
  238.     qualignore[i] = QUAL_NLK; /* PATCH_NULL [04 Apr 1993] : added */
  239.     is_rawc[i] = (len > 0);   /* PATCH_NULL [30 Apr 1993] : added */
  240.  
  241.     switch(len) {
  242.     case 1:     /*    ESC/DEL/BS/TAB/NKx  */
  243.         if ((buf[0] & 0x7F) >= 32 && (buf[0] & 0x7F) < 127)
  244.         ctoa[i] = buf[0];
  245.  
  246.         switch(buf[0]) {
  247.         case 0x1B:    lname[SP_START+1] |= i; break;
  248.         case 0x7F:    lname[SP_START+2] |= i; break;
  249.         case 0x08:    lname[SP_START+3] |= i;
  250.             lname[SP_START+4] |= i; break;
  251.         case 0x09:    lname[SP_START+5] |= i; break;
  252.         case '@':                                                           /* for setmap cdn     */
  253.         case '[':                                                           /* for setmap d,f,i,n */
  254.         case '(': if (i > 0x3A) lname[NS_START+0] |= LN(0,0,*buf,i); qualignore[i] &= ~QUAL_NLK; break; /* for setmap usa/gb  */
  255.         case '°':                                                           /* for setmap cdn     */
  256.         case ']':                                                           /* for setmap d,i,f,n */
  257.         case ')': if (i > 0x3A) lname[NS_START+1] |= LN(0,0,*buf,i); qualignore[i] &= ~QUAL_NLK; break; /* for setmap usa/gb  */
  258.         case '/': if (i > 0x3A) lname[NS_START+2] |= i; qualignore[i] &= ~QUAL_NLK; break;
  259.         case '*': if (i > 0x3A) lname[NS_START+3] |= i; qualignore[i] &= ~QUAL_NLK; break;
  260.         case '+': if (i > 0x3A) lname[NS_START+4] |= i; qualignore[i] &= ~QUAL_NLK; break;
  261.         case '-': if (i > 0x3A) lname[NS_START+5] |= i; qualignore[i] &= ~QUAL_NLK; break;
  262.         case '.': if (i > 0x3A) lname[NS_START+6] |= i; qualignore[i] &= ~QUAL_NLK; break;
  263.         default:
  264.         if (i >= 0x0F && isdigit (buf[0])) {
  265.             lname[N0_START+buf[0]-'0'] |= i;
  266.             qualignore[i] &= ~QUAL_NLK; /* PATCH_NULL [04 Apr 1993] : added */
  267.         } /* if */
  268.         } /* switch */
  269.         break;
  270.  
  271.     case 2:     /*    cursor            */
  272.         if (buf[0] == 0x9B) {
  273.  
  274.         switch(buf[1]) {
  275.         case 0x41:  lname[CS_START+0] |= i;  break;
  276.         case 0x42:  lname[CS_START+1] |= i;  break;
  277.         case 0x43:  lname[CS_START+2] |= i;  break;
  278.         case 0x44:  lname[CS_START+3] |= i;  break;
  279.         } /* switch */
  280.  
  281.         } /* if */
  282.         break;
  283.  
  284.     case 3:     /*    function/help        */
  285.         if (buf[0] == 0x9B && buf[2] == 0x7E) {
  286.  
  287.         if (buf[1] == 0x3F)
  288.             lname[SP_START+0] |= i;
  289.         if (buf[1] >= 0x30 && buf[1] <= 0x39)
  290.             lname[buf[1]-0x30+F1_START] |= i;
  291.  
  292.         } /* if */
  293.         break;
  294.     } /* switch */
  295.     } /* for */
  296.  
  297.     /* ---- init Shifted Keys (cstoa) */
  298.  
  299.     ievent.ie_Qualifier        = IEQUALIFIER_LSHIFT;
  300.     ievent.ie_position.ie_addr = NULL;
  301.     for (i = 0; i < 128; ++i) {
  302.     ievent.ie_Code = i;
  303.  
  304.     len = RawKeyConvert (&ievent,buf,32,NULL);
  305.  
  306.     if (len == 1)
  307.         cstoa[i] = buf[0];
  308.     } /* for */
  309.  
  310.     /* ---- calc CtlC - Code */
  311.  
  312.     {
  313.     struct keyspec ks;
  314.  
  315.     get_codequal ("c", &ks);
  316.  
  317.     CtlC = KS_CODE(&ks);
  318.     } /* block */
  319. } /* keyboard_init */
  320.  
  321.  
  322.  
  323. /*****************************************************************************
  324.  
  325.     NAME
  326.     cqtoa
  327.  
  328.     PARAMETER
  329.     KEYSPEC *ks
  330.  
  331.     RESULT
  332.     a ptr to the string that is the readable
  333.     form of that key-stroke (static)
  334.  
  335.     RETURN
  336.     UBYTE *
  337.  
  338.     DESCRIPTION
  339.  
  340.     NOTES
  341.     we return a ptr to a static array of char
  342.     for only use of Qualifiers simply use KS_CODE(ks) == -1
  343.  
  344.     BUGS
  345.     (none known)
  346.  
  347.     EXAMPLES
  348.  
  349.     SEE ALSO
  350.  
  351.     INTERNALS
  352.  
  353.     HISTORY
  354.     14-Dez-92 b_null created
  355.     14-Jan-93 b_null added UP
  356.     04 Apr 93 b_null added REP,NLK,PER*
  357.     16 Jun 93 b_null introduced "struct keyspec"
  358.     29-Jun-94 b_null changed Types
  359.  
  360. ******************************************************************************/
  361.  
  362. Prototype UBYTE* cqtoa (KEYSPEC *ks);
  363.  
  364. UBYTE *cqtoa (KEYSPEC *ks)
  365. {
  366.     static UBYTE buf[32];
  367.     UBYTE    *ptr = buf;
  368.     int      i;
  369.  
  370.     /* ---- Build Qual part */
  371.  
  372.     if (KS_QUAL(ks) & QUAL_SHIFT)
  373.     *ptr++ = 's';
  374.     if (KS_QUAL(ks) & QUAL_CTRL)
  375.     *ptr++ = 'c';
  376.     if (KS_QUAL(ks) & QUAL_ALT)
  377.     *ptr++ = 'a';
  378.     if (KS_QUAL(ks) & QUAL_AMIGA)
  379.     *ptr++ = 'A';
  380.     if (KS_QUAL(ks) & QUAL_LMB)
  381.     *ptr++ = 'L';
  382.     if (KS_QUAL(ks) & QUAL_MMB)
  383.     *ptr++ = 'M';
  384.     if (KS_QUAL(ks) & QUAL_RMB)
  385.     *ptr++ = 'R';
  386.  
  387.     if (KS_QUAL(ks) & QUAL_XTX)
  388.     *ptr++ = 'x';
  389.     if (KS_QUAL(ks) & QUAL_XTY)
  390.     *ptr++ = 'y';
  391.     if (KS_QUAL(ks) & QUAL_XTZ)
  392.     *ptr++ = 'z';
  393.  
  394.     if (KS_QUAL(ks) & QUAL_PRX)
  395.     *ptr++ = 'X';
  396.     if (KS_QUAL(ks) & QUAL_PRY)
  397.     *ptr++ = 'Y';
  398.     if (KS_QUAL(ks) & QUAL_PRZ)
  399.     *ptr++ = 'Z';
  400.  
  401.     if (KS_QUAL(ks) & QUAL_NLK)
  402.     *ptr++ = 'n';
  403.     if (KS_QUAL(ks) & QUAL_REP)
  404.     *ptr++ = 'r';
  405.     if (KS_QUAL(ks) & QUAL_UP)
  406.     *ptr++ = 'u';
  407. /*
  408. **  --- That little fragment was added
  409. **    to be able to get the extended qualifiers with already existing functions
  410. **    U might uncomment it, if U wanna get information about
  411. **    which quals have been set with QUALIFIER
  412. */
  413.     if (KS_CODE(ks) == (-1)) {
  414. /* printf("U used a wrong undef\n"); */
  415.     *ptr++ = 0;
  416.     return(buf); /* do not append a code-value */
  417.     } /* if */
  418.  
  419.     /* ---- Append the '-' between Qual & Code */
  420.  
  421.     /* if (KS_QUAL(ks)) */       /* commented out for better readable keyfiles */
  422.     *ptr++ = '-';
  423.  
  424.     /* ---- Try it as a Long Name */
  425.  
  426.     for (i = 0; i < sizeof(lname)/sizeof(lname[0]); ++i) {
  427.     if ((lname[i]&0xFF) == KS_CODE(ks)) {
  428.         *ptr++ = (lname[i]>>24);
  429.         *ptr++ = (lname[i]>>16);
  430.         *ptr++ = (lname[i]>>8);
  431.         break;
  432.     } /* if */
  433.     } /* for */
  434.  
  435.     if (i == sizeof(lname)/sizeof(lname[0])) {
  436.  
  437.     /* ---- Try it as a normal Code */
  438.  
  439.     *ptr = ctoa[KS_CODE(ks)];
  440.  
  441.     if (*ptr) {
  442.         ptr ++;
  443.     /* PATCH_NULL [14 Feb 1993] : direct access to rawcodes ... */
  444.     } else {
  445.  
  446.         /* ---- Try it as a HexValue */
  447.  
  448.         sprintf (ptr, "0x%02x",KS_CODE(ks));
  449.         ptr += 4;
  450.     } /* if */
  451.     /* PATCH_NULL [14 Feb 1993] : ... direct access to rawcodes */
  452.     } /* if no spcname */
  453.  
  454.     *ptr++ = 0;
  455.     return buf;
  456. } /* cqtoa */
  457.  
  458.  
  459. /*****************************************************************************
  460.  
  461.     NAME
  462.     get_codequal
  463.  
  464.     PARAMETER
  465.     VAL (char *, string)
  466.     VAR (struct keyspec, ks)
  467.  
  468.     RESULT
  469.     success: TRUE == ok; FALSE == error (unknown string)
  470.  
  471.     RETURN
  472.     BOOL
  473.  
  474.     DESCRIPTION
  475.     we try to extract Qualifier- and Keycode -information
  476.     from an ascii-String and put the found values into
  477.     pcode and pqual
  478.  
  479.     NOTES
  480.     for only use of Qualifiers simply use code == -1
  481.  
  482.     BUGS
  483.     (none known)
  484.  
  485.     EXAMPLES
  486.  
  487.     SEE ALSO
  488.  
  489.     INTERNALS
  490.  
  491.     HISTORY
  492.     14-Dec-92 b_null included & modified
  493.     14-Jan-93 b_null added UP
  494.     04 Apr 93 b_null added REP,NLK,PER*
  495.     16 Jun 93 b_null introduced "struct keyspec"
  496.     29-Jun-94 b_null changed Types
  497.  
  498. ******************************************************************************/
  499.  
  500. Prototype BOOL get_codequal (const UBYTE *str, KEYSPEC *ks);
  501.  
  502. BOOL get_codequal (const UBYTE *str, KEYSPEC *ks)
  503. {
  504.     const char * base = str;
  505.     TQUAL     qual;
  506.     short     i;
  507.  
  508.     KS_MASK(ks) = QUALMASK;
  509.  
  510.     qual = 0;
  511.  
  512.     /* ---- Get the Qualifier */
  513.  
  514.     if (strlen(str) > 1) {
  515.     for (; *str && *str != '-'; ++str) {
  516.         /* ---- Why the hell did I use IF insted of SWITCH? */
  517.         if (*str == 's')
  518.         qual |= QUAL_SHIFT;
  519.         if (*str == 'c')
  520.         qual |= QUAL_CTRL;
  521.         if (*str == 'a')
  522.         qual |= QUAL_ALT;
  523.         if (*str == 'A')
  524.         qual |= QUAL_AMIGA;
  525.         if (*str == 'L')
  526.         qual |= QUAL_LMB;
  527.         if (*str == 'M')
  528.         qual |= QUAL_MMB;
  529.         if (*str == 'R')
  530.         qual |= QUAL_RMB;
  531.  
  532.         if (*str == 'x')
  533.         qual |= QUAL_XTX;
  534.         if (*str == 'y')
  535.         qual |= QUAL_XTY;
  536.         if (*str == 'z')
  537.         qual |= QUAL_XTZ;
  538.  
  539.         if (*str == 'X')
  540.         qual |= QUAL_PRX;
  541.         if (*str == 'Y')
  542.         qual |= QUAL_PRY;
  543.         if (*str == 'Z')
  544.         qual |= QUAL_PRZ;
  545.  
  546.         if (*str == 'n')
  547.         qual |= QUAL_NLK;
  548.         if (*str == 'u')
  549.         qual |= QUAL_UP;
  550.         if (*str == 'r')
  551.         qual |= QUAL_REP;
  552.  
  553.         if (!qual)
  554.         goto notqual;
  555.     } /* for */
  556.  
  557.     /* ---- test if that was really a Qualified Key, and not only a LongName */
  558.  
  559.     if (*str == 0) {
  560.         qual = 0;
  561.         str = base;
  562.     } else {
  563.         ++str;
  564.     } /* if */
  565.  
  566.     } /* if */
  567.  
  568.     /* ---- Get the Code */
  569.  
  570. notqual:
  571.     if (strlen(str) != 1) {           /* ---- long name */
  572.     short shift = 24;
  573.     long mult = 0;
  574.     UBYTE c;
  575.     UBYTE * ptr = str; /* PATCH_NULL [14 Feb 1993] : added */
  576.  
  577.     /* ---- create LongName-Entry */
  578.  
  579.     KS_QUAL(ks) = qual;
  580.     while ((c = *str) && shift >= 8) {
  581.         c = tolower (c);
  582.         mult |= c << shift;
  583.         shift -= 8;
  584.         ++str;
  585.     } /* while */
  586.  
  587.     /* ---- Search LongNames */
  588.  
  589.     for (i = 0; lname[i]; ++i) {
  590.         if (mult == (lname[i] & 0xFFFFFF00)) {
  591.         KS_CODE(ks) = lname[i] & 0xFF;
  592.         return TRUE;
  593.         } /* if */
  594.     } /* for */
  595.  
  596.     /* ---- Try it as a HexNumber */
  597.  
  598.     /* PATCH_NULL [14 Feb 1993] : direct access to raw-codes ... */
  599.     /* NOTE             : we cannot save that value yet!!! */
  600. /* printf ("testing %s with hex\n", str); */
  601.     if ((*ptr == '0') && ((ptr[1]|0x20) == 'x')) {
  602.         i = (strtol (ptr, &str, 0x10) & 0xff);
  603.         if (ptr != (UBYTE *)str) {
  604.         KS_CODE(ks) = i;
  605.         return TRUE;
  606.         } /* if scanned */
  607.     } /* if */
  608.     /* PATCH_NULL [14 Feb 1993] : ... direct access to raw-codes */
  609.  
  610.     } else {            /*    ---- single character keycap */
  611.  
  612.     /* ---- check the normal codes */
  613.  
  614.     for (i = 0; i < sizeof(ctoa); ++i) {
  615.         if (*str == ctoa[i]) {
  616.         KS_CODE(ks) = i;
  617.         KS_QUAL(ks) = qual;
  618.         return TRUE;
  619.         } /* if */
  620.     } /* for */
  621.  
  622.     /* ---- check the shifted codes */
  623.  
  624.     for (i = 0; i < sizeof(cstoa); ++i) {
  625.         if (*str == cstoa[i]) {
  626.         KS_CODE(ks) = i;
  627.         KS_QUAL(ks) = qual|QUAL_SHIFT;
  628.         return TRUE;
  629.         } /* if */
  630.     } /* for */
  631.     } /* if */
  632.     return FALSE;
  633. } /* get_codequal */
  634.  
  635.  
  636. /*****************************************************************************
  637.  
  638.     NAME
  639.     iqual2qual
  640.  
  641.     PARAMETER
  642.     ULONG  iqual
  643.     int    blen
  644.     char * buf
  645.     int    code ; TCODE code ?
  646.  
  647.     RESULT
  648.     the [X]DME-internal qualifier referred by the intuition qualifier qual;
  649.  
  650.     RETURN
  651.     TQUAL
  652.  
  653.     DESCRIPTION
  654.     transform the different intuition - Qualifiers to [X]DME-Qualifiers
  655.     (if we have caps-lock and buffer contains
  656.     one lower char, it is used like shift)
  657.  
  658.     NOTES
  659.  
  660.     BUGS
  661.     (none known)
  662.  
  663.     EXAMPLES
  664.  
  665.     SEE ALSO
  666.  
  667.     INTERNALS
  668.  
  669.     HISTORY
  670.     14-Dec-92 b_null included & modified
  671.     14-Jan-93 b_null added UP
  672.     04 Apr 93 b_null added REP,NLK,PER*
  673.     29-Jun-94 b_null changed Types
  674.  
  675. ******************************************************************************/
  676.  
  677. Prototype TQUAL iqual2qual (ULONG qual, int blen, char * buf, int code);
  678.  
  679. TQUAL iqual2qual (ULONG iqual, int blen, char * buf, int code) /* (unsigned long iqual, int blen, char * buf, TCODE code) */
  680. {
  681.     TQUAL q2 = 0;
  682.  
  683.     if (iqual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  684.     q2 |= QUAL_SHIFT;
  685.     if (iqual & (IEQUALIFIER_CONTROL))
  686.     q2 |= QUAL_CTRL;
  687.     if (iqual & (IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND))
  688.     q2 |= QUAL_AMIGA;
  689.     if (iqual & (IEQUALIFIER_LALT|IEQUALIFIER_RALT))
  690.     q2 |= QUAL_ALT;
  691.  
  692. /* We should replace "isalpha(buf[1])" by "((buf[1] != ToUpper(buf[1])) || (buf[1] != ToLower(buf[1])))"    */
  693. /* Thats much longer, ok, but that way we can be sure to use a real uppercase character, also for non-Ascii */
  694. /* an alternative was to check for the reverse - MapANSI(&buf[1],1,&buf[4], 1) and then check for */
  695. /* a SHIFT-qual in our result */
  696.  
  697.     if (!(q2 & QUAL_SHIFT))
  698.     /* if ((iqual & IEQUALIFIER_CAPSLOCK) && blen == 1 && isalpha (buf[1])) */
  699.     if ((iqual & IEQUALIFIER_CAPSLOCK) && blen == 1 && (isalpha (buf[1]) || ((buf[1] != ToUpper(buf[1])) || (buf[1] != ToLower(buf[1]))))) /* PATCH_NULL 27-09-93 */
  700.         q2 |= QUAL_SHIFT;
  701.  
  702.     if (iqual & IEQUALIFIER_LEFTBUTTON)
  703.     q2 |= QUAL_LMB;
  704.     if (iqual & IEQUALIFIER_MIDBUTTON)
  705.     q2 |= QUAL_MMB;
  706.     if (iqual & (IEQUALIFIER_RBUTTON))
  707.     q2 |= QUAL_RMB;
  708.  
  709.     if (iqual & (EXTQUALIFIER_X))
  710.     q2 |= QUAL_XTX;
  711.     if (iqual & (EXTQUALIFIER_Y))
  712.     q2 |= QUAL_XTY;
  713.     if (iqual & (EXTQUALIFIER_Z))
  714.     q2 |= QUAL_XTZ;
  715.  
  716.     if (iqual & (PERQUALIFIER_X))
  717.     q2 |= QUAL_PRX;
  718.     if (iqual & (PERQUALIFIER_Y))
  719.     q2 |= QUAL_PRY;
  720.     if (iqual & (PERQUALIFIER_Z))
  721.     q2 |= QUAL_PRZ;
  722.  
  723.     if (iqual & (EXTQUALIFIER_NLK))
  724.     q2 |= QUAL_NLK;
  725.     if (iqual & (IEQUALIFIER_REPEAT))
  726.     q2 |= QUAL_REP;
  727.  
  728. #if 0
  729.     if (iqual & (EXTQUALIFIER_UP))
  730.     q2 |= QUAL_UP;
  731.     q2 |= (QUAL_UP & code);
  732. #endif
  733.  
  734.     if (code & 0x080)
  735.     q2 |= QUAL_UP;
  736.  
  737.     return q2;
  738. } /* iqual2qual */
  739.  
  740.  
  741. /*****************************************************************************
  742.  
  743.     NAME
  744.     qual2iqual
  745.  
  746.     PARAMETER
  747.     TQUAL qual ; might be changed to KEYSPEC
  748.  
  749.     RESULT
  750.     Intuition Qualifiers, which represent the [X]DME - qualifiers
  751.  
  752.     RETURN
  753.     ULONG
  754.  
  755.     DESCRIPTION
  756.     simple transformation of internal representation for
  757.     Qualifiers to a possible Amiga-representation
  758.  
  759.     NOTES
  760.     very slow
  761.     !ATTN!    there is currently no possibility to
  762.         transform the UP-Qualifier
  763.  
  764.     BUGS
  765.     QUAL_UP is not supported (we needed a Code for it)
  766.  
  767.     EXAMPLES
  768.  
  769.     SEE ALSO
  770.     iqual2qual
  771.  
  772.     INTERNALS
  773.  
  774.     HISTORY
  775.     14-Dez-92 b_null created
  776.     14-Jan-93 b_null added UP
  777.     04 Apr 93 b_null added REP,NLK,PER*
  778.     29-Jun-94 b_null changed Types
  779.  
  780. ******************************************************************************/
  781.  
  782. Prototype ULONG qual2iqual (TQUAL qual);
  783.  
  784. ULONG qual2iqual (TQUAL qual)
  785. {
  786.     ULONG iq2 = 0;
  787.  
  788.     if (qual & QUAL_XTX)
  789.     iq2 |= EXTQUALIFIER_X;
  790.     if (qual & QUAL_XTY)
  791.     iq2 |= EXTQUALIFIER_Y;
  792.     if (qual & QUAL_XTZ)
  793.     iq2 |= EXTQUALIFIER_Z;
  794.  
  795.     if (qual & QUAL_PRX)
  796.     iq2 |= PERQUALIFIER_X;
  797.     if (qual & QUAL_PRY)
  798.     iq2 |= PERQUALIFIER_Y;
  799.     if (qual & QUAL_PRZ)
  800.     iq2 |= PERQUALIFIER_Z;
  801.  
  802.     if (qual & QUAL_NLK)
  803.     iq2 |= EXTQUALIFIER_NLK;
  804.     if (qual & QUAL_REP)
  805.     iq2 |= IEQUALIFIER_REPEAT;
  806. #if 0
  807.     if (qual & QUAL_UP)        /* that info must be placed into Code */
  808.     iq2 |= EXTQUALIFIER_UP;
  809. #endif
  810.  
  811.     if (qual & QUAL_SHIFT)
  812.     iq2 |= IEQUALIFIER_LSHIFT;
  813.     if (qual & QUAL_CTRL)
  814.     iq2 |= IEQUALIFIER_CONTROL;
  815.     if (qual & QUAL_AMIGA)
  816.     iq2 |= IEQUALIFIER_LCOMMAND;
  817.     if (qual & QUAL_ALT)
  818.     iq2 |= IEQUALIFIER_LALT;
  819.     if (qual & QUAL_LMB)
  820.     iq2 |= IEQUALIFIER_LEFTBUTTON;
  821.     if (qual & QUAL_MMB)
  822.     iq2 |= IEQUALIFIER_MIDBUTTON;
  823.     if (qual & QUAL_RMB)
  824.     iq2 |= IEQUALIFIER_RBUTTON;
  825.  
  826.     return iq2;
  827. } /* qual2iqual */
  828.  
  829.  
  830. /*****************************************************************************
  831.  
  832.     NAME
  833.     a2iqual
  834.  
  835.     PARAMETER
  836.     const UBYTE* str
  837.     ULONG       *piqual
  838.  
  839.     RESULT
  840.     success: TRUE == ok; FALSE == any error
  841.  
  842.     RETURN
  843.     BOOL
  844.  
  845.     DESCRIPTION
  846.     convert an ascii string into Input-Qualifiers
  847.     we check each char of the string and set the according bit
  848.     the string may be NULL-terminated or "-"-terminated
  849.     any unknown char causes "return (0)"
  850.  
  851.     NOTES
  852.  
  853.     BUGS
  854.     (none known)
  855.  
  856.     EXAMPLES
  857.  
  858.     SEE ALSO
  859.  
  860.     INTERNALS
  861.  
  862.     HISTORY
  863.     14-Dez-92 null created
  864.     14-Jan-93 b_null added UP
  865.     04 Apr 93 b_null added REP,NLK,PER*
  866.     29-Jun-94 b_null changed Types
  867.  
  868. ******************************************************************************/
  869.  
  870. Prototype BOOL a2iqual (const UBYTE *str, ULONG *piqual);
  871.  
  872. BOOL a2iqual (const UBYTE* str, ULONG *piqual)
  873. {
  874.     *piqual = 0;
  875.     for (; *str; str++) {
  876.     switch (*str) {
  877.     case 'a':   *piqual |= IEQUALIFIER_LALT;        break;
  878.     case 'A':   *piqual |= IEQUALIFIER_LCOMMAND;    break;
  879.     case 's':   *piqual |= IEQUALIFIER_LSHIFT;      break;
  880.     case 'L':   *piqual |= IEQUALIFIER_LEFTBUTTON;  break;
  881.     case 'M':   *piqual |= IEQUALIFIER_MIDBUTTON;   break;
  882.     case 'R':   *piqual |= IEQUALIFIER_RBUTTON;     break;
  883.  
  884.     case 'u':   *piqual |= EXTQUALIFIER_UP;         break;
  885.     case 'n':   *piqual |= EXTQUALIFIER_NLK;        break;
  886.     case 'r':   *piqual |= IEQUALIFIER_REPEAT;      break;
  887.  
  888.     case 'x':   *piqual |= EXTQUALIFIER_X;          break;
  889.     case 'y':   *piqual |= EXTQUALIFIER_Y;          break;
  890.     case 'z':   *piqual |= EXTQUALIFIER_Z;          break;
  891.  
  892.     case 'X':   *piqual |= PERQUALIFIER_X;          break;
  893.     case 'Y':   *piqual |= PERQUALIFIER_Y;          break;
  894.     case 'Z':   *piqual |= PERQUALIFIER_Z;          break;
  895.  
  896.     case '-':   return TRUE;
  897.     default:    return FALSE;
  898.     } /* switch */
  899.     } /* for */
  900.     return TRUE;
  901. } /* a2iqual */
  902.  
  903.  
  904. /*****************************************************************************
  905.  
  906.     NAME
  907.     iqual2a
  908.  
  909.     PARAMETER
  910.     ULONG iqual
  911.  
  912.     RESULT
  913.     the string that corresponds to iqual  (static)
  914.  
  915.     RETURN
  916.     UBYTE *
  917.  
  918.     DESCRIPTION
  919.     create a string representing the readble form of Intuition Qualifiers
  920.  
  921.     NOTES
  922.     this is a slow routine, as we do not
  923.     immediately evaluated the string, but
  924.     use iqual2qual and cqtoa (but it works :-)
  925.  
  926.     BUGS
  927.     (none known)
  928.  
  929.     EXAMPLES
  930.  
  931.     SEE ALSO
  932.     iqual2qual(), cqtoa
  933.  
  934.     INTERNALS
  935.  
  936.     HISTORY
  937.     14-Dez-92 null created
  938.     29-Jun-94 b_null changed Types
  939.  
  940. ******************************************************************************/
  941.  
  942. Prototype UBYTE *iqual2a (ULONG iqual);
  943.  
  944. UBYTE *iqual2a (ULONG iqual)
  945. {
  946.     struct keyspec ks = {0, 0, ~0};
  947.     KS_QUAL(&ks) = iqual2qual (iqual, 0, NULL, 0);
  948.     return (cqtoa (&ks));
  949. } /* iqual2a */
  950.  
  951.  
  952. /*****************************************************************************
  953.  
  954.     NAME
  955.     init_kb
  956.     (exit_kb - removed)
  957.  
  958.     PARAMETER
  959.     void
  960.  
  961.     RESULT
  962.     -/-
  963.  
  964.     RETURN
  965.     void
  966.  
  967.     DESCRIPTION
  968.     entry code for Keyboard Control
  969.  
  970.     NOTES
  971.     this is the lowest level on Amiga Software, we use;
  972.     exit_kb is removed, so user cannot call it any more
  973.     init_kb is "__AUTOINIT" so user need not call it
  974.     (he must indeed, if his compiler does not support __autoinit)
  975.  
  976.     BUGS
  977.     for unknown reasons, we must not close ConsoleDevice,
  978.         else the machine is going to crash
  979.  
  980.     EXAMPLES
  981.  
  982.     SEE ALSO
  983.     reset_hash
  984.  
  985.     INTERNALS
  986.     Open the Console.Device and call keyboard_init
  987.  
  988.     HISTORY
  989.     15-Dez-92  b_null created
  990.     15-Jan-93  b_null removed exit_kb
  991.     29-06-94   b_null removed KC_Used
  992.  
  993. ******************************************************************************/
  994.  
  995. Prototype void init_kb (void);
  996.  
  997. MK_AUTOINIT( init_kb )
  998. {
  999.     struct IOStdReq cio;
  1000.  
  1001. /* printf ("init_kb\n"); */
  1002.  
  1003.     if (!ConsoleDevice) {
  1004.     OpenDevice ("console.device", -1, (struct IORequest *)&cio, 0);
  1005.     ConsoleDevice = (struct Library *)cio.io_Device;
  1006.     keyboard_init ();
  1007.     } /* if */
  1008. } /* init_kb */
  1009.  
  1010.  
  1011. /* FUNCTION TO BE KILLED AGAIN */
  1012.  
  1013. /*****************************************************************************
  1014.  
  1015.     NAME
  1016.     CtoA
  1017.  
  1018.     PARAMETER
  1019.     TCODE c
  1020.  
  1021.     RESULT
  1022.     ctoa[c]
  1023.  
  1024.     RETURN
  1025.     UBYTE
  1026.  
  1027.     DESCRIPTION
  1028.     this function was created to hide the stucture ctoa
  1029.  
  1030.     ctoa is designed to check, IF a KeyCode c represents a
  1031.     single ascii character and WHICH one
  1032.  
  1033.     NOTES
  1034.     a macro might be possible, too;
  1035.     but then You have to declare ctoa non-static
  1036.  
  1037.     ctoa is initialized by keyboard_init(), so
  1038.     any call to CtoA before keyboard initialisation is undefined
  1039.  
  1040.     BUGS
  1041.     none known
  1042.  
  1043.     EXAMPLES
  1044.  
  1045.     SEE ALSO
  1046.     ctoa
  1047.  
  1048.     INTERNALS
  1049.  
  1050.     HISTORY
  1051.     30-Dez-92 b_null created
  1052.     15-Jan-93 b_null documented
  1053.     29-Jun-94 b_null changed Types
  1054.  
  1055. ******************************************************************************/
  1056.  
  1057. Prototype UBYTE  CtoA (TCODE c);
  1058.  
  1059. UBYTE CtoA (TCODE c)
  1060. {
  1061.     return (ctoa[c]);
  1062. } /* CtoA */
  1063.  
  1064.  
  1065.  
  1066. #ifdef NOT_DEF     /* FUNCTION TO BE KILLED AGAIN */
  1067.  
  1068. /*****************************************************************************
  1069.  
  1070.     NAME
  1071.     CignoreQ
  1072.  
  1073.     PARAMETER
  1074.     TCODE c
  1075.  
  1076.     RESULT
  1077.     qualignore[c]
  1078.  
  1079.     RETURN
  1080.     TQUAL
  1081.  
  1082.     DESCRIPTION
  1083.     this function was created to hide the structure qualignore
  1084.  
  1085.     qualignore is designed to check, IF a KeyCode c ignores
  1086.     any [X]DME qualifiers and WHICH ones
  1087.  
  1088.     NOTES
  1089.     a macro might be possible, too;
  1090.     but then You have to declare qualignore non-static
  1091.  
  1092.     qualignore is initialized by keyboard_init(), so
  1093.     any call to CignoreQ before keyboard initialisation is undefined
  1094.  
  1095.     ***  that function is not (yet) used (any more)  ***
  1096.  
  1097.     BUGS
  1098.     none known
  1099.  
  1100.     EXAMPLES
  1101.  
  1102.     SEE ALSO
  1103.     qualignore
  1104.  
  1105.     INTERNALS
  1106.  
  1107.     HISTORY
  1108.     04 Apr 93 b_null created & documented
  1109.  
  1110. ******************************************************************************/
  1111.  
  1112. Prototype TQUAL CIgnoreQ (TCODE c);
  1113.  
  1114. TQUAL CignoreQ (TCODE c)
  1115. {
  1116.     return (qualignore[c]);
  1117. } /* CignoreQ */
  1118.  
  1119. #endif        /* FUNCTION TO BE KILLED AGAIN */
  1120.  
  1121.  
  1122. /*****************************************************************************
  1123.  
  1124.     NAME
  1125.     IsRawC
  1126.  
  1127.     PARAMETER
  1128.     KEYSPEC *ks
  1129.  
  1130.     RESULT
  1131.     is_rawc[c]
  1132.  
  1133.     RETURN
  1134.     Bool
  1135.  
  1136.     DESCRIPTION
  1137.     this function was created to hide the structure is_rawc
  1138.     lateron I added a check for QUAL_UP
  1139.  
  1140.     is_rawc is designed to check for the possibility, if
  1141.     we can use a keycode as RawKey for DeadKeyConvert or not
  1142.  
  1143.     NOTES
  1144.     a macro might be possible, too;
  1145.     but then You have to declare is_rawc non-static
  1146.  
  1147.     is_rawc is initialized by keyboard_init(), so
  1148.     any call to IsRawC before keyboard initialisation
  1149.     is undefined
  1150.  
  1151.     BUGS
  1152.     none known
  1153.  
  1154.     EXAMPLES
  1155.  
  1156.     SEE ALSO
  1157.     is_rawc
  1158.  
  1159.     INTERNALS
  1160.  
  1161.     HISTORY
  1162.     30 Apr 93 b_null created & documented
  1163.     17 Jun 93 b_null introduced "struct keyspec" , QUAL_UP-check
  1164.     27-06-94  b_null added check for QUAL_ALT/SHIFT
  1165.     29-Jun-94 b_null changed Types
  1166.  
  1167. ******************************************************************************/
  1168.  
  1169. Prototype BOOL IsRawC (KEYSPEC *ks);
  1170.  
  1171. BOOL IsRawC (KEYSPEC *ks)
  1172. {
  1173.     return (((is_rawc[KS_CODE(ks)] != 0) || KS_QUAL(ks) & (QUAL_SHIFT|QUAL_ALT))&& ((KS_QUAL(ks) & QUAL_UP) == 0))? TRUE: FALSE;
  1174. } /* IsRawC */
  1175.  
  1176.  
  1177. /*****************************************************************************
  1178.  
  1179.     NAME
  1180.     DeadKeyConvert
  1181.  
  1182.     PARAMETER
  1183.     struct IntuiMessage * msg
  1184.     UBYTE *           buf
  1185.     int              bufsize
  1186.     struct KeyMap *       keymap
  1187.  
  1188.     RESULT
  1189.     actual - the number of characters in the buffer, -2 if no
  1190.     RawKey was given or -1 if a buffer overflow was about to occur.
  1191.  
  1192.     RETURN
  1193.     int
  1194.  
  1195.     DESCRIPTION
  1196.     convert any RawKey-Code to (VanillaKey) an ASCII-String
  1197.  
  1198.     NOTES
  1199.     this function is only used by keycontrol.keyctl
  1200.     but it for itself uses ConsoleDevice, so I could not
  1201.     decide where to put it.
  1202.  
  1203.     BUGS
  1204.  
  1205.     EXAMPLES
  1206.  
  1207.     SEE ALSO
  1208.     console.device/RawKeyConvert
  1209.  
  1210.     INTERNALS
  1211.     erzeuge eine iorequest mit den allernotwendigsten Eintraegen
  1212.     und lasse sie auswerten
  1213.  
  1214.     HISTORY
  1215.     15-Dez-92 b_null moved to keycontrol.c
  1216.     16.Dez.92 b_null documented
  1217.     15-Jan-93 b_null moved to keycodes.c
  1218.  
  1219. ******************************************************************************/
  1220.  
  1221. Prototype int DeadKeyConvert (struct IntuiMessage * msg, UBYTE * buf, int bufsize, struct KeyMap * keymap);
  1222.  
  1223. int DeadKeyConvert (struct IntuiMessage * msg, UBYTE * buf, int bufsize, struct KeyMap * keymap)
  1224. {
  1225.     static struct InputEvent ievent = {
  1226.     NULL, IECLASS_RAWKEY
  1227.     };
  1228.  
  1229.     if (msg->Class != RAWKEY)
  1230.     return(-2);
  1231.  
  1232.     ievent.ie_Code           = msg->Code;
  1233.     ievent.ie_Qualifier        = msg->Qualifier;
  1234.     ievent.ie_position.ie_addr = *((APTR *)msg->IAddress);
  1235.  
  1236. /* printf ("DeadKeyConvert %02x + %08lx\n", msg->Code, ievent.ie_position.ie_addr); */
  1237.  
  1238.     return (RawKeyConvert (&ievent, (char *)buf, bufsize, keymap));
  1239. } /* DeadKeyConvert */
  1240.  
  1241.  
  1242. /******************************************************************************
  1243. *****  ENDE keycodes.c
  1244. ******************************************************************************/
  1245.